package org.budo.mongo.jdbc.driver;

import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;

import org.budo.jdbc.driver.AbstractBudoJdbcConnection;
import org.budo.jdbc.driver.statement.JdbcStatement;
import org.budo.mongo.jdbc.driver.executor.DefaultMongoStatementExecutor;
import org.budo.mongo.jdbc.driver.executor.MongoStatementExecutor;

import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;

/**
 * @author li
 */
@Slf4j
@Setter
@Getter
@Accessors(chain = true)
public class BudoMongoJdbcConnection extends AbstractBudoJdbcConnection {
    private MongoStatementExecutor _statementExecutor;

    /**
     * 延迟初始化 MongoStatementExecutor
     */
    public MongoStatementExecutor statementExecutor() {
        if (null != this._statementExecutor) {
            return this._statementExecutor;
        }

        synchronized (this) {
            if (null != this._statementExecutor) {
                return this._statementExecutor;
            }

            return this._statementExecutor = new DefaultMongoStatementExecutor(this.jdbcUrl());
        }
    }

    /**
     * 不重复关闭
     */
    public void close() throws SQLException {
        if (!this.isClosed()) {
            return;
        }

        super.close();

        if (null != this._statementExecutor) {
            this._statementExecutor.close();
        }
    }

    public void setAutoCommit(boolean autoCommit) throws SQLException {
        if (!autoCommit) {
            log.error("#45 setAutoCommit(" + autoCommit + ") is not supported, autoCommit=" + autoCommit);
        }

        super.setAutoCommit(autoCommit);
    }

    public DatabaseMetaData getMetaData() throws SQLException {
        return new BudoMongoJdbcDatabaseMetaData() //
                .connection(this);
    }

    @SuppressWarnings("resource")
    public Statement createStatement() throws SQLException {
        return new BudoMongoJdbcStatement() //
                .setConnection(this);
    }

    @SuppressWarnings("resource")
    public PreparedStatement prepareStatement(String sql) throws SQLException {
        JdbcStatement jdbcStatement = this.statementParser().parse(sql);

        return (PreparedStatement) new BudoMongoJdbcPreparedStatement() //
                .setJdbcStatement(jdbcStatement) //
                .setConnection(this);//
    }

    @Override
    public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
        BudoMongoJdbcPreparedStatement prepareStatement = (BudoMongoJdbcPreparedStatement) this.prepareStatement(sql);
        prepareStatement.setAutoGeneratedKeys(autoGeneratedKeys); // 支持, insert 后取 _id
        return prepareStatement;
    }
}
